package cz.acies.uniql.dialect;

import java.sql.*;
import java.util.*;


import cz.acies.uniql.connect.*;
import cz.acies.uniql.metadata.FieldMetaData;
import cz.acies.uniql.metadata.IndexesMetaData;
import cz.acies.uniql.metadata.PrimaryKeyMetaData;
import cz.acies.uniql.metadata.TableMetaData;
import cz.acies.uniql.sql.*;
import cz.acies.uniql.sql.element.UniQLField;
import cz.acies.uniql.sql.element.UniQLLimit;
import cz.acies.uniql.sql.functions.SQLFunc;

/**
 * T��da MySQLDialect.
 * 
 */
public class MySQLDialect extends Dialect
{
	// DBMetaData variables
	// TableMetaData variables
	// FieldMetadata variables
	// PrimaryKeyMetaData variables
	// IndexMetaData variables
	
	// Convert Element variables
	// Convert values variables

	/**
	 * Konstruktor tridy MySQLDialect.
	 */
	public MySQLDialect() {
		super();
		setSchema("");
		
		registerColumnType( Types.BIT, "bit" );
		registerColumnType( Types.BIGINT, "bigint" );
		registerColumnType( Types.SMALLINT, "smallint" );
		registerColumnType( Types.TINYINT, "tinyint" );
		registerColumnType( Types.INTEGER, "int($l)" );
		registerColumnType( Types.CHAR, "char($l)" );
		registerColumnType( Types.VARCHAR, "varchar($l)" );
		registerColumnType( Types.FLOAT, "double(15,5)" );
		registerColumnType( Types.REAL, "double(15,5)" );
		registerColumnType( Types.DOUBLE, "double($p,$s)" );
		registerColumnType( Types.DATE, "date" );
		registerColumnType( Types.TIME, "time" );
		registerColumnType( Types.TIMESTAMP, "datetime" );
		registerColumnType( Types.VARBINARY, "blob", 65535);		
		registerColumnType( Types.LONGVARBINARY, "blob", 65535);
		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
		registerColumnType( Types.BLOB, "blob", 65535);
		registerColumnType( Types.CLOB, "text", 65535);
		registerColumnType( Types.LONGVARCHAR, "text", 65535);

		// ----- register functions -------------------------------------------
				
		// Special functions 
		registerFunction("sql_calc_found_rows", "SQL_CALC_FOUND_ROWS ");
		registerFunction("rownumber", "" /*"SQL_CALC_FOUND_ROWS"*/);
		registerFunction("over", "");
		registerFunction("connection_id", "CONNECTION_ID()");
		
		// Convert functions		
		registerFunction("convert", "$1");
		registerFunction("text_to_varchar", "$1");
		registerFunction("to_varchar", "$1");
		registerFunction("to_number", "$1");
		registerFunction("to_date", "$1");
		registerFunction("to_timestamp", "$1");
		registerFunction("date_to_varchar", "$1");
		
		// String functions
		registerFunction("left", "LEFT($1, $2)");
		registerFunction("right", "RIGHT($1, $2)");
		registerFunction("substring", "SUBSTRING($1, $2[, $3])");
		registerFunction("substring_index", "SUBSTRING_INDEX($1, $2, $3)");
		registerFunction("ltrim", "LTRIM($1)");
		registerFunction("rtrim", "RTRIM($1)");
		registerFunction("trim", "LTRIM(RTRIM($1))");
		registerFunction("lpad", "LPAD($1, $2, $3)");
		registerFunction("rpad", "RPAD($1, $2, $3)");
		registerFunction("length", "LENGTH($1)");
		registerFunction("char_length", "CHAR_LENGTH($1)");
		registerFunction("char", "CHAR($1)");
		registerFunction("upper", "UPPER($1)");
		registerFunction("lower", "LOWER($1)");

		registerFunction("concat", "CONCAT($n{, })");
		registerFunction("password", "PASSWORD($1)");
		//registerFunction("password", "$1");
		registerFunction("locate", "LOCATE($1, $2, $3)");
		registerFunction("replace", "REPLACE($1, $2, $3)");
		
		// Date & time functions
		registerFunction("now", "NOW()");
		registerFunction("dateadd", "$3 + INTERVAL ($2) $1");
		registerFunction("date_add", "DATE_ADD($3, INTERVAL ($2) $1)");
		registerFunction("date_sub", "DATE_SUB($1, INTERVAL ($2) $3)");
		registerFunction("date_format", "DATE_FORMAT($1, $2)");
		registerFunction("to_days", "TO_DAYS($1)");
		registerFunction("datediff_day", "(TO_DAYS($1) - TO_DAYS($2))");        // Vrac� po�et dn�  
		registerFunction("year", "YEAR($1) ");
		registerFunction("month", "MONTH($1) ");
		registerFunction("day", "DAY($1)");
		
		// Logic functions
		registerFunction("if", "IF($1, $2, $3)");
		registerFunction("isnull", "ISNULL($1)");
		registerFunction("not isnull", "NOT ISNULL($1)");
		registerFunction("ifnull", "IFNULL($1, $2)");
		registerFunction("if_isnull", "IF(ISNULL($1),$2,$3)");
				
		// Numeric functions
		registerFunction("abs", "ABS($1)");
		registerFunction("round", "ROUND($1, $2)");
		
		//
		// DBMetaData variables
		// TableMetaData variables
		// FieldMetadata variables
		FMD_IDENTITY_BUILD_PART = "AUTO_INCREMENT";
		FMD_IDENTITY_PARSE_COLUNM_NAME = "REMARKS";
		FMD_IDENTITY_APPNED_INDEX_KEY = true;
		//FMD_NULL_COLUMN_STRING = "NULL";
		
		// PrimaryKeyMetaData variables
		// IndexMetaData variables		
		// Convert Element variables
		// Convert values variables
	
	}

	// ----- Quoted methods ---------------------------------------------------

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#LQ()
	 */
	public String LQ() { return "`"; }

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#RQ()
	 */
	public String RQ() { return "`"; }

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#CTI_LQ()
	 */
	public String CTI_LQ() { return "`"; }

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#CTI_RQ()
	 */
	public String CTI_RQ() { return "`"; }

	// ----- Database connection methods --------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getSQLConnDriver()
	 */
	public String getSQLConnDriver() {
		String driver = super.getSQLConnDriver(); 
		if (driver != null) return driver;
		return "org.gjt.mm.mysql.Driver";
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getSQLConnPrefix()
	 */
	public String getSQLConnPrefix() {
		return "jdbc:mysql:";
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#generateSQLConnUrl(cz.acies.uniql.connect.SQLConnect)
	 */
	public String generateSQLConnUrl(SQLConnect sqlconn) throws SQLException {
		String url = sqlconn.getPrefix();
		String host = sqlconn.getHost();
		if (host == null) throw new SQLException("Host in URL address is .NULL.");
		url += "//"+host;
	
		String port = sqlconn.getPort();
		if (port != null){
			url += ":"+port;
		}
		String database = sqlconn.getDatabase();
		if (port == null && database == null) throw new SQLException("Port AND database in URL address is .NULL.");
		if (database != null){
			url += "/"+database;
		}
		return url;	
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#parseURL(java.lang.String)
	 */
	public Properties parseURL(String url) {
		try {
			Properties prop = new Properties();
			
			String shl = "";
			String shr = "";
			
			int pos = url.indexOf("?");
			if (pos > -1) {
				shl = url.substring(0, pos);
				shr = url.substring(pos+1);
			} else {
				shl = url;
			}
			if (shl != null && shl.length() > 0) {
				pos = shl.indexOf("//");
				if (pos > -1) {
					String prefix = shl.substring(0, pos);
					shl = shl.substring(pos+2);
					prop.put("prefix", prefix);
				} 
				pos = shl.indexOf("/");
				if (pos > -1) {
					String host = shl.substring(0, pos);
					shl = shl.substring(pos+1);
					pos = host.indexOf(":");
					if (pos > -1) {
						String port = host.substring(pos+1);
						host = host.substring(0, pos);
						prop.put("port", port);
					}
					prop.put("host", host);
				}
				if (shl.length() > 0) {
					String database = shl;
					prop.put("database", database);
				}
			}
			if (shr != null && shr.length() > 0) {
				StringTokenizer st = new StringTokenizer(shr,"&");
				while (st.hasMoreTokens()) {
					String element = st.nextToken();
					pos = element.indexOf("=");
					if (pos > -1) {
						String key = element.substring(0, pos);
						String value = "";
						if (pos < element.length()) value = element.substring(pos+1, element.length());
						prop.put(key, value);
					}
				}
			}
			//System.out.println("prop = "+prop);			
			return prop;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getSchema()
	 */
	public String getSchema() {
		return "";
	}

	// ----- ColumnType methods -----------------------------------------------
	
	// ----- ReservedKeywords methods -----------------------------------------
	
	// ----- Fn Methods -------------------------------------------------------
	
	//* ***********************************************************************
	//* Database Mapping methods
	//* ***********************************************************************
	
	// ----- DBMetaData methods -----------------------------------------------
	
	// ----- TableMetaData metdods --------------------------------------------
	
	// ----- FieldMetadata methods --------------------------------------------
	/*
	public int getIdentityColumnStyle() {
		return 0;
	}
	*/
	public String getIdentityColumnString() {
		return "auto_increment";
	}
	
	public boolean isIdentityColumn(String value) {
		if (value == null || value.length() == 0) return false;
		return (value.toUpperCase().equals("AUTO_INCREMENT"));
	}

	// ----- PrimaryKey Constraint --------------------------------------------
	
	// ----- IndexMetaData methods --------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#generateIndexName(java.lang.String, java.lang.String, java.lang.String)
	 */
	public String generateIndexName(String tableName, String indexName, String sufix) {
		return "IDX_"+tableName+"_"+indexName;
	}
	
	// ----- Convert Element methods ------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getNullColumnString()
	 */
	//public String getNullColumnString() { return "NULL"; }

	// ----- Convert Values methods -------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#showProcessList()
	 */
	public String getValueString(String value, int length) {
		if (value.matches("\\s+")) {
			value = value.trim();
		} else {
			value = this.text2SQL(value);
		}
		if (value.length() > length) {
			value = value.substring(0, length);
		}
		return "'"+value+"'";
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#showProcessList()
	 */	
	public String getValueString(String value) {
		if (value.matches("\\s+")) {
			value = "'"+value.trim()+"'";
		} else {
			value = "'"+this.text2SQL(value)+"'";
		}
		return value;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#showProcessList()
	 */
	public String getValueBlob(String value) {
		if (value.matches("\\s+")) {
			value = "'"+value.trim()+"'";
		} else {
			value = "'"+this.text2SQL(value)+"'";
		}
		return value;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#showProcessList()
	 */	
	public String getValueClob(String value) {
		if (value.matches("\\s+")) {
			value = "'"+value.trim()+"'";
		} else {
			value = "'"+this.text2SQL(value)+"'";
		}
		return value;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#text2SQL(java.lang.String)
	 */
	public String text2SQL(String input)  {
		StringBuffer buf = new StringBuffer("");
		for (int i = 0; i < input.length(); i++) {
			if (input.charAt(i) == '\\') {
				buf.append("\\\\");
			} else if (input.charAt(i) == '\'') {
				buf.append("\\\'");				
			} else {
				buf.append(input.charAt(i));
			}
		}
		return buf.toString();
	}
	
	// ----- DDL methods ------------------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getCreateTableString(com.smart4web.db.structure.TableMetaData)
	 */
	/*
	public String getCreateTableString(TableMetaData tbmd) {
		return "";
	}
	*/
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getCreateTableFieldString(com.smart4web.db.structure.FieldMetaData)
	 */
	public String getCreateTableFieldString(FieldMetaData fmd) {
		StringBuffer sb = new StringBuffer("");
		if (fmd.isPrefix()) sb.append(this.LQ() + fmd.getTable() + this.RQ() + ".");
		
		sb.append((isKeyword(fmd.getName())) ? (fmd.getName()+"_") : fmd.getName());
		fmd.setTypeName(getColumnTypeString(
		    fmd.getSqlType(), fmd.getSize(), fmd.getDecimal())
		);
		sb.append(LQ() + fmd.getTypeName() + RQ());

		if (fmd.isNullable()) {
			if (fmd.hasValue()) {
				sb.append("DEFAULT " + fmd.getValue() + " ");
			}
			sb.append(getNullColumnString());
		} else {
			sb.append("DEFAULT " + fmd.getValue() + " ");
			sb.append(" NOT NULL ");
		}
		return sb.toString();		
	}
	
	/* DROP */
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getDropTableString(java.lang.String, java.lang.String)
	 */
	public String getDropTableString(String schema,String table) {
		return "DROP TABLE "+table;
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getCreateIndexesString(com.smart4web.db.structure.IndexesMetaData)
	 */
	public String getCreateIndexesString(IndexesMetaData tbmd) {
		return "";
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getCreateIndexesList(com.smart4web.db.structure.IndexesMetaData)
	 */
	public List<String> getCreateIndexesList(IndexesMetaData ixmd) {
		Vector<String> list = new Vector<String>();
		for (Enumeration<Map<String, Object>> e = ixmd.elements(); e.hasMoreElements();) {
			Hashtable<String, Object> params = (Hashtable<String, Object>)e.nextElement();
			//System.out.println("H2Dialect.getCreateIndexesList().params = "+params);
			Hashtable columns = (Hashtable)params.get("columns");
			
			String name = (String)params.get("INDEX_NAME");
			String tableName = (String)params.get("TABLE_NAME");
			//System.out.println("INDEX_NAME = "+name);	
			String query = "";
			if (name.equals("PRIMARY")) {
			} else {
				//String asc_desc = (String)params.get("ASC_OR_DESC");
				boolean nonunique = ((Boolean)params.get("NON_UNIQUE")).booleanValue();
				
				String colstr = "( ";
				//String colName = "";
				name = "IDX_" + ixmd.getTable();   
				for (int i = 0; i < columns.size(); i++) {
					String columnname = (String)columns.get(new Integer(i+1));
					//columnname = (ReservedKeywords.isReservedKeyword(columnname)) ? (columnname+"_") : columnname;
					colstr += LQ() + columnname + RQ();
					if (i < columns.size()-1) {
						colstr += ",";
					}
					if (i == 0) name += "_"+columnname; 
				}
				colstr += " )";
								
				query = "CREATE ";
				if (!nonunique) { 
					query += "UNIQUE ";
				}
				//if (name)
				// query += asc_desc;
				query += "INDEX "+name+" ON "+ixmd.getTable()+" "+colstr;
				list.addElement(query);
			}
		}
		return list;
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#getDropIndexString(java.lang.String, java.lang.String)
	 */
	public String getDropIndexString(String table, String name) {
		return "DROP INDEX "+name;
	}
	
	/**
	 * 
	 */
	public synchronized void execAlterTable(AlterTable alterTable, Connection conn) throws Exception {
		Statement stmt = null;		
		try {
			Dialect d = alterTable.getDialect();
			String actionType = alterTable.getActionType();
			String table = alterTable.getTableName();
			FieldMetaData fmd = alterTable.fmd();
			
			String[] query = new String[0];
			if (actionType.equals(AlterTable.ADD_COLUMN)) {
				fmd.setTypeName(this.getColumnTypeString(fmd.getSqlType(), fmd.getSize(), fmd.getDecimal()));	
				String column = fmd.getName();
				String tableStr = d.LQ() + table + d.RQ();
				String columnStr = d.LQ() + column + d.RQ();				
				query = new String[1];
				query[0] = "ALTER TABLE " + tableStr + " " +
					"ADD COLUMN " + columnStr + " " + fmd.getTypeName() + 
						((fmd.isNullable()) ? " NULL" : " NOT NULL") +
						" DEFAULT " + fmd.getValue();
				
			} else if (actionType.equals(AlterTable.MODIFY_COLUMN)) {
				fmd.setTypeName(this.getColumnTypeString(fmd.getSqlType(), fmd.getSize(), fmd.getDecimal()));
				
				String column = fmd.getName();
				String tableStr = d.LQ() + table + d.RQ();
				String columnStr = d.LQ() + column + d.RQ();
				
				int sqltype = fmd.getSqlType();
				String value = " DEFAULT " + fmd.getValue();
				if (sqltype == Types.LONGVARCHAR && fmd.isNullable()) value = "";
				query = new String[1];
				query[0] = "ALTER TABLE " + tableStr + " " +
					"MODIFY COLUMN " + columnStr + " " + fmd.getTypeName() + 
						((fmd.isNullable()) ? " NULL" : " NOT NULL") +
						" " + value;
				//System.out.println("MySQLDialect.execAlterTable( CHANGE ):\n"+query[0]);
				/*				 
				"ALTER TABLE "+table+" 
					CHANGE "+table+"."+columnName+" "+table+"."+columnName+" "+type+
						(isNotNull ? " NOT NULL" : "")+(defaultValue.length()!=0 ? " DEFAULT '"+defaultValue+"'" : "")
				*/
			} else if (actionType.equals(AlterTable.DROP_COLUMN)) {
				
				String column = fmd.getName();				
				String tableStr = d.LQ() + table + d.RQ();
				String columnStr = d.LQ() + column + d.RQ();
	
				query = new String[1];
				query[0] = "ALTER TABLE " + tableStr + " DROP COLUMN " + columnStr;
			} else if (actionType.equals(AlterTable.ADD_PRIMARY_KEY) || actionType.equals(AlterTable.DROP_PRIMARY_KEY)) {
				TableMetaData tbmd = alterTable.getDBMetaData().getTable(table);
				PrimaryKeyMetaData pkmd = tbmd.getPrimaryKey();
				
				String column = pkmd.getColumn();
				String tableStr = d.LQ() + table + d.RQ();
				String columnStr = d.LQ() + column + d.RQ();
				String constrait = this.getPKConstraintKey(table, column);
				
				query = new String[1];
				if (actionType.equals(AlterTable.ADD_PRIMARY_KEY)) {
					query[0] = "ALTER TABLE " + tableStr + " ADD PRIMARY KEY (" + columnStr + ")";
				} else {
					query[0] = "ALTER TABLE " + tableStr + " DROP PRIMARY KEY";					
				}
			} else if (actionType.equals(AlterTable.ADD_INDEX) || actionType.equals(AlterTable.DROP_INDEX)) {
				String tableStr = d.LQ() + table + d.RQ();
				Map<String, Object> map = alterTable.getIndex();
				Map<Integer, String> columns = (Map<Integer, String>)map.get("columns");
				String columnName = columns.get(1);
				String columnStr = d.LQ() + columnName + d.RQ();
				
				query = new String[3];

				if (actionType.equals(AlterTable.ADD_INDEX)) {
					query[1] = "ALTER TABLE " + tableStr + " ADD INDEX("+columnStr+")";
				} else {
					query[1] = "ALTER TABLE " + tableStr + " DROP INDEX " + columnStr + "";
				}
			} else if (actionType.equals(AlterTable.ADD_FULLTEXT) || actionType.equals(AlterTable.DROP_FULLTEXT)) {
				String tableStr = d.LQ() + table + d.RQ();
				Map<String, Object> map = alterTable.getIndex();
				Map<Integer, String> columns = (Map<Integer, String>)map.get("columns");
				String columnName = columns.get(1);
				String columnStr = d.LQ() + columnName + d.RQ();
				
				query = new String[3];

				if (actionType.equals(AlterTable.ADD_FULLTEXT)) {
					query[1] = "ALTER TABLE " + tableStr + " ADD FULLTEXT("+columnStr+")";
				} else {
					query[1] = "ALTER TABLE " + tableStr + " DROP INDEX " + columnStr + "";
				}				
			}
			stmt = conn.createStatement();
			for (int i = 0; i < query.length; i++) {
				if (query[i] != null) {
					try {
						//System.out.println(query[i]);
						stmt.execute(query[i]);	
					} catch (Exception exc) {
						System.out.println("[ERROR] MySQLDialect.execAlterTable(): "+exc.getMessage()+"\n\t"+query[i]);
					}						
				}
			}
		} catch (Exception exc) {
			exc.printStackTrace();
		} finally {
			try { if (stmt != null) stmt.close(); } catch (SQLException e) {}
		} 
	}
	
	// ----- FullText methods -------------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#encodeFullText(java.lang.String)
	 */
	public String encodeFullText(String value) throws Exception {
		
		String encode_char_ISO = 
		"A��BCEDIE�IFGHI�JKLAYMNOO���PQRAOS�T�U�U�VWXY�Z�a��bcedie�i�fghi�jkla�mnoo���pqraos1t�u�u�vwxy�z3_";

		String decode_char_ascii =
		"AAABCCDDEEEFGHIIJKLLLMNNOOOOPQRRRSSTTUUUUVWXYYZZAAABCCDDEEEEFGHIIJKLLLMNNOOOOPQRRRSSTTUUUUVWXYYZZ_";
		String encode_char_znak = "\".,/;][=-+|{}:?><)(~!@#$%^&*()'`";
		
		String fullText = "";
		for (int _i = 0; _i < encode_char_ISO.length(); _i++) {
			value = value.replace(encode_char_ISO.charAt(_i), decode_char_ascii.charAt(_i));
		}
		if (value.indexOf("-") != -1) {
			fullText += "-";
			value = value.substring(1, value.length());
		} else {
			fullText += "+";
			if (value.indexOf("+") != -1) {
				value = value.substring(1, value.length());
			}
		}
		for (int i = 0; i < encode_char_znak.length(); i++) {
			value = value.replace(encode_char_znak.charAt(i), '_');
		}
		fullText = fullText.toUpperCase();
		return fullText; 
	}

	// ----- LOCK & UNLOCK TABLE methtods -------------------------------------

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#lockTable(java.lang.String)
	 */
	public String lockTable(String table) {
		return "LOCK TABLES "+table+" WRITE;";
		 
	}

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#unlockTable(java.lang.String)
	 */
	public String unlockTable(String table) {
		return "UNLOCK TABLES;";
	}

	// ----- QueryRebuilder methods -------------------------------------------

	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#generateLimitQuery(cz.acies.uniql.sql.SelectQuery)
	 */
	public synchronized String generateLimitQuery(SelectQuery query) throws Exception {
		UniQLLimit limit = query.getLimit();
		int first = limit.getFirstResult();
		int count = limit.getCountResult();
		
		String s = query.translate()+"\n";
		s += "LIMIT "+first+", "+count;
		return s;
	}
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#generateRowCountQuery(cz.acies.uniql.sql.SelectQuery)
	 */
	public synchronized SelectQuery generateRowCountQuery(SelectQuery query) throws Exception {
		try {
			ArrayList fields = query.getFields();
			fields.clear();
			query.removeLimit();
			query.removeOrderBy();
			query.removeGroupBy();
			UniQLField f = new UniQLField(new SQLFunc("COUNT").addParam("*")).as("ROW_COUNT");
			query.addField(f);
			//System.out.println("isLimited = "+query.isLimited()); 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return query;
	}

	// -----  -----------------------------------------------------------------
	
	/* (non-Javadoc)
	 * @see cz.acies.uniql.dialect.Dialect#showProcessList()
	 */
	public String showProcessList() {
		return "SHOW PROCESSLIST;";
	}
}
